using System;
using OracleInternal.Common;
using OracleInternal.ServiceObjects;

namespace Oracle.ManagedDataAccess.Client
{
	[Serializable]
	public sealed class OracleError
	{
		private string m_dataSource;

		private string m_procedure;

		private string m_message;

		private int m_number;

		private int m_parseErrorOffset = -1;

		private int m_arrayBindIndex = -1;

		private bool m_isRecoverable;

		public string DataSource => m_dataSource;

		public string Message => m_message;

		public int Number => m_number;

		public int ParseErrorOffset => m_parseErrorOffset;

		public string Procedure => m_procedure;

		public string Source => "Oracle Data Provider for .NET, Managed Driver";

		public int ArrayBindIndex => m_arrayBindIndex;

		internal bool IsRecoverable => m_isRecoverable;

		internal OracleError(int errNumber, int parseErrorOffset, string dataSrc, string procedure, string errMsg)
			: this(errNumber, dataSrc, procedure, errMsg)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, OracleTraceTag.Entry, OracleTraceClassName.OracleError, OracleTraceFuncName.ctor);
			}
			m_parseErrorOffset = parseErrorOffset;
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, OracleTraceTag.Exit, OracleTraceClassName.OracleError, OracleTraceFuncName.ctor);
			}
		}

		internal OracleError(int errNumber, string dataSrc, string procedure, string errMsg)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, OracleTraceTag.Entry, OracleTraceClassName.OracleError, OracleTraceFuncName.ctor);
			}
			try
			{
				m_number = errNumber;
				m_dataSource = dataSrc;
				m_procedure = procedure;
				if (errMsg == null || errMsg.Length == 0)
				{
					m_message = OracleStringResourceManager.GetErrorMesg(errNumber);
				}
				else
				{
					m_message = errMsg;
				}
				m_isRecoverable = IsErrorRecoverable(m_number);
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, OracleTraceTag.Error, OracleTraceClassName.OracleError, OracleTraceFuncName.ctor, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, OracleTraceTag.Exit, OracleTraceClassName.OracleError, OracleTraceFuncName.ctor);
				}
			}
		}

		internal OracleError(int errNumber, string dataSrc, string procedure, string errMsg, int arrayBindIndex)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, OracleTraceTag.Entry, OracleTraceClassName.OracleError, OracleTraceFuncName.ctor);
			}
			try
			{
				m_number = errNumber;
				m_dataSource = dataSrc;
				m_procedure = procedure;
				if (errMsg == null || errMsg.Length == 0)
				{
					m_message = OracleStringResourceManager.GetErrorMesg(errNumber);
				}
				else
				{
					m_message = errMsg;
				}
				m_arrayBindIndex = arrayBindIndex;
				m_isRecoverable = IsErrorRecoverable(m_number);
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, OracleTraceTag.Error, OracleTraceClassName.OracleError, OracleTraceFuncName.ctor, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, OracleTraceTag.Exit, OracleTraceClassName.OracleError, OracleTraceFuncName.ctor);
				}
			}
		}

		private bool IsErrorRecoverable(int errcode)
		{
			if (!OracleConnectionImpl.IsConnectionAlive(errcode))
			{
				return true;
			}
			return false;
		}
	}
}
